import { Subscription } from 'rxjs';
import { DataRPermits } from './../../../../../models/dataRPermits';
import { NzModalService } from 'ng-zorro-antd/modal';
import { ExceptionHandler } from './../../../../../handler/exception.handler';
import { AfterViewInit, Component, OnInit, ViewContainerRef, OnDestroy } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
import { BaseService, DataRegisterService, WorkflowService } from 'src/app/services';
import { EventManagerService } from 'src/app/services/event-manager.service';
import { OrganizationService } from 'src/app/services/organization.service';
import { PersonnelService } from 'src/app/services/personnel.service';
import { UploadService } from 'src/app/services/upload.service';
import { EngineService } from '../../../services/engine.service';
import { BaseFieldComponent } from '../base-field/base-field.component';
import { PermitService } from 'src/app/services/permit.service';
import { PermitConfig, PermitConfigId } from '../../../models';
import { PermitPerviewModalComponent } from 'src/app/pages/companyInfo/organization/permission/permit-perview-modal/permit-perview-modal.component';
import { OrganizationTree } from 'src/app/models/organization';
import { WorkflowPageService } from 'src/app/common/page-render/workflow-page-container/workflow-page.service';

@Component({
  selector: 'zepride-task-member',
  templateUrl: './task-member.component.html',
  styleUrls: ['./task-member.component.less', '../field.common.less']
})
export class TaskMemberComponent extends BaseFieldComponent implements OnInit, AfterViewInit, OnDestroy {
  rowDatas: RowData[] = [];
  morePermitModalVisible = false;
  curRowData: RowData;
  permitConfig: PermitConfig[] = [
    { mode: 'query', permitId: '查看', permitName: '', authObjectId: '' },
    { mode: 'edit', permitId: '编辑', permitName: '', authObjectId: '' }
  ];
  isAuthorized = true;
  workflowUpdatedSub: Subscription;
  departmentNodes: OrganizationTree[] = [];
  employeeList: OrganizationTree[] = [];
  dataRegisterId: string;
  projectPermits: DataRPermits[];

  constructor(
    protected engineService: EngineService,
    protected baseSvr: BaseService,
    protected eventSvr: EventManagerService,
    protected orgSvr: OrganizationService,
    public uploadService: UploadService,
    protected msg: NzMessageService,
    public userSvr: PersonnelService,
    public permitSvr: PermitService,
    public workflowSvr: WorkflowService,
    public modal: NzModalService,
    public viewContainerRef: ViewContainerRef,
    public wfpSvr: WorkflowPageService,
    protected dataRegisterService: DataRegisterService
  ) {
    super(engineService, baseSvr, eventSvr, orgSvr, uploadService, msg, dataRegisterService);
  }
  ngOnDestroy(): void {
    if (this.workflowUpdatedSub) {
      this.workflowUpdatedSub.unsubscribe();
    }
  }

  async ngOnInit() {
    // await this.getProjectPermits();
    await this.getDepartmentAndEmployee();
    // this.rowDatas = [];
    if (this.bindData) {
      for (const userId of this.bindData) {
        if (this.componentData.extends.selectedUsers && this.componentData.extends.selectedUsers.length > 0) {
          const has = this.componentData.extends.selectedUsers.find(x => x == userId);
          await this.addRow(userId, has ? true : false);
        }
        else {
          await this.addRow(userId);
        }

      }
    }
    else {
      if (this.componentData.extends.selectedUsers && this.componentData.extends.selectedUsers.length > 0) {
        for (const userId of this.componentData.extends.selectedUsers) {
          await this.addRow(userId, true);
        }
      }
      else {
        if (this.rowDatas.length == 0) {
          await this.addRow();
        }
      }
    }

    this.workflowUpdatedSub = this.wfpSvr.workflowUpdated.subscribe(async data => {
      if (!data) {
        return;
      }
      this.dataRegisterId = data.id;
      this.projectPermits = data.datarPermits;
    });
  }

  ngAfterViewInit() {
    setTimeout(() => {
      const authData = this.setAuthorityData();
      this.zeprideAuthorityData = {
        ...authData,
        afterChecked: this.afterAuthChecked.bind(this)
      };
    }, 0);
  }

  showMore(rowData: RowData) {
    const modal = this.modal.create({
      nzTitle: '所属权限预览',
      nzContent: PermitPerviewModalComponent,
      nzViewContainerRef: this.viewContainerRef,
      nzWidth: 1000,
      nzComponentParams: {
        mode: 'preview',
        userPermits: rowData.permitList
      },
      nzFooter: null
    });
  }

  async getUserPermit() {
    try {
      if (this.dataRegisterId && this.projectPermits && this.projectPermits.length > 0) {
        for (const rowData of this.rowDatas) {
          const p = this.projectPermits.filter(x => x.accountId == rowData.accountId);
          rowData.permitList = p;
        }
      }
      else {
        for (const rowData of this.rowDatas) {
          const p = await this.permitSvr.getUserPermits(rowData.userId, rowData.accountId);
          rowData.permitList = p;

          rowData.permitList.forEach(item => {
            item.accountId = rowData.accountId;
          });
        }
      }

    } catch (error) {
      ExceptionHandler.current.handleError(error);
    }
  }

  async getDepartmentAndEmployee() {
    this.departmentNodes = await this.orgSvr.getOrganizationTrees({
      objectName: 'Department'
    });

    this.employeeList = await this.orgSvr.getOrganizationTrees({ objectName: 'User' });

    this.employeeList = this.employeeList.filter(x => x.parentId);

    this.departmentNodes.forEach(departmnet => {
      (departmnet as any).children = this.employeeList.filter(x => {
        (x as any).isLeaf = true;
        return x.parentId == departmnet.id;
      });
    });

    this.departmentNodes = this.departmentNodes.filter(x => (x as any).children.length != 0);
  }

  userChange(nodeIds: string[], rowData: RowData) {
    if (nodeIds.length <= 1) {
      return;
    }
    const userNodeId = nodeIds[1];
    const employeeNode = this.employeeList.find(x => x.id == userNodeId);
    if (employeeNode) {
      rowData.accountId = employeeNode.object.accountId;
      rowData.userId = employeeNode.objectId;
      this.getUserPermit();
      this.setData(this.rowDatas.map(x => x.userId));
    }
  }

  async addRow(userId?: string, notDel?: boolean) {
    let obj = new RowData(
      this.employeeList[0].objectId,
      this.employeeList[0].object.accountId,
      [this.employeeList[0].parentId, this.employeeList[0].id]
    );

    if (userId) {
      const userNodeItem = this.employeeList.find(x => x.objectId == userId);
      if (userNodeItem) {
        obj = new RowData(
          userNodeItem.objectId,
          userNodeItem.object.accountId,
          [userNodeItem.parentId, userNodeItem.id]
        );

        // obj.permitList = permits;
      }
    }

    if (notDel != undefined) {
      obj.notDel = notDel;
    }

    this.rowDatas.push(obj);
    // if (!permits) {
    await this.getUserPermit();
    // }
    this.setData(this.rowDatas.map(x => x.userId));
    return obj;
  }

  delRow(index) {
    if (!this.isAuthorized) {
      return;
    }
    this.rowDatas.splice(index, 1);
  }


  async validate() {
    // TODO： 权限不够的是返回错误
    // this.engineService.fieldErrors || (this.engineService.fieldErrors = []);
    // this.engineService.fieldErrors.push({
    //   identifyId: this.componentData.identifyId,
    //   inValid: false,
    //   errors: [],
    //   name: this.componentData.name,
    //   errorMsg: '权限不足'
    // });

    // return false;

    return true;
  }

  pageSavedHandle = async () => {
    // TODO:
    // console.log('pageSavedHandle', this.rowDatas);

    this.setData(this.rowDatas.map(x => x.userId));

    this.workflowSvr.involvedPersonChange$.next(this.rowDatas);
  }

  handleOk(): void {
    this.morePermitModalVisible = false;
  }

  handleCancel(): void {
    this.morePermitModalVisible = false;
  }

  afterAuthChecked(params: {
    permitId: PermitConfigId;
    isAuthorized: boolean;
  }) {
    if (!params.isAuthorized) {
      this.isAuthorized = false;
    }
  }
}

class RowData {
  userId: string;
  nodeIds: string[];
  permitList?: DataRPermits[];
  accountId?: string;
  notDel?: boolean;
  get permitDisplay() {
    if (this.permitList) {
      return this.permitList.map(x => x.permitId).join(',');
    }
    else {
      return '';
    }
  }

  constructor(userId: string, accountId: string, nodeIds: string[]) {
    this.userId = userId;
    this.accountId = accountId;
    this.nodeIds = nodeIds;
  }
}
